package com.javaspeak.newfeaturesjava.projectcoin.trywithresourcesstatement;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Code that used to look like:
 * <pre>
 * {@code
 * 
 * BufferedWriter bufferedWriter = null;
 * 
 * try {
 *     bufferedWriter =
 *          new BufferedWriter( new FileWriter( textFile ) );
 *          
 *     bufferedWriter.write( text );     
 *  }
 *  finally {
 *     
 *     if ( bufferedWriter != null ){
 *     
 *      bufferedWriter.close();
 *     }
 *  }
 * </pre>
 * Can now be written:
 * <pre>
 * {@code
 * try (
 *
 *     BufferedWriter bufferedWriter =
 *         new BufferedWriter( new FileWriter( textFile ) );
 * ){
 *     bufferedWriter.write( text );
 * }
 * 
 * </pre>
 * The reason this is possible is that BufferedWriter extends Writer which
 * implements Closeable.  Closeable extends AutoCloseable which has a close()
 * method that has to be implemented.  When the Writer code has executed in the 
 * try-resources-catch, close() is automatically called as if it had been placed
 * in a finally block.
 * <p>
 * Note that the field which needs closing is placed in smooth brackets () after 
 * the "try" keyword.
 * 
 * @author John Dickerson
 */
public class ApplicationTryWithResourcesStatement {

    /**
     * Creates a temporary directory if it does not exist already
     * 
     * @return
     * @throws IOException
     */
    private File createTempDirectory() throws IOException {

        String tempDirPath =
            System.getProperty( "java.io.tmpdir" );

        File tempDir = new File( tempDirPath );

        File applicationTempDir = 
                new File( tempDir, "TryWithResourcesStatement" );

        if ( ! applicationTempDir.mkdirs() ){
            
            if ( applicationTempDir.exists() ){
            
                System.out.println( "Could not make directory: " + 
                        applicationTempDir.getAbsolutePath() + 
                            " because it exists already" );
            }
            else if ( applicationTempDir.canWrite() ){
                
                System.out.println( "Could not make directory: " + 
                        applicationTempDir.getAbsolutePath() + 
                            " because do not have write permissions" );
            }
            else {
                
                System.out.println( "Could not make directory: " + 
                        applicationTempDir.getAbsolutePath() + 
                            ". Reason unknown" );
            }
        }   
        else {
            
            System.out.println( 
                  "Made directory: " + applicationTempDir.getAbsolutePath() );
        }

        return applicationTempDir;
    }


    /**
     * Writes some text to a file
     * 
     * @param textFile The file to save
     * @param text The text to save in the file
     * @throws IOException if problem writing to file
     */
    public void writeToFile( File textFile, String text ) throws IOException {

        try (

            BufferedWriter bufferedWriter =
                new BufferedWriter( new FileWriter( textFile ) );
        ){
            bufferedWriter.write( text );
        }
    }
    
    
    /**
     * Reads some text from a file
     * 
     * @param textFile File to read
     * @return String text content of file
     * @throws FileNotFoundException if cannot find File
     * @throws IOException if error reading file
     */
    public String readFile( File textFile ) 
                throws FileNotFoundException, IOException {

        try (

            BufferedReader bufferedReader =
                new BufferedReader( new FileReader( textFile ) );
        ){
            
            StringBuilder textToReturn = new StringBuilder();
            String line;
            
            while ( ( line = bufferedReader.readLine() ) != null ){
                
                textToReturn.append( line );
            }
            
            return textToReturn.toString();
        }
    }


    /**
     * Runs the example
     * 
     * @throws IOException
     */
    public void runExample() throws IOException {

        File applicationTempDir = createTempDirectory();

        File textFile = new File(
                applicationTempDir, "applicationMultiCatchExceptions.txt" );

        String text = "hello";

        writeToFile( textFile, text );
        
        String readText = readFile( textFile );
        
        System.out.println( readText );
    }

    
    public static void main(String[] args) throws IOException {

        ApplicationTryWithResourcesStatement application =
             new ApplicationTryWithResourcesStatement();

        application.runExample();
    }
}
